package hu.myai.indicators;

import hu.myai.api.indicators.AbstractIndicator;
import hu.myai.indicators.util.Fibonacci;
import hu.myai.indicators.util.FibonacciAgent;
import hu.myai.model.IndicatorVO;
import hu.myai.model.TrendLineVO;
import hu.myai.util.pool.IndicatorPool;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * It provides the Y distance between last tick and Fibonacci resistance level.
 * Numerous resistance could be. Parameter indicates the number of the
 * resistance. parameter 1 is the closest resistance.
 *
 * @author bozbalint
 *
 */
public class FibResistanceIndicator extends AbstractIndicator {

    /**
     * The object used when logging debug,errors,warnings and info.
     * */
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * Carrier of the fibonacci levels.
     * */
    FibonacciAgent fibonacciAgent;

    /**
     * Last indicator value
     * */
    Double lastValue;

    public FibResistanceIndicator(Double parameter) {
        super(parameter);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void init() {

        // sync the indicator with the pool
        fibonacciAgent = (FibonacciAgent) IndicatorPool.indicatorManager(new FibonacciAgent(3.0), tickSourceID);
        // TODO Auto-generated method stub

    }

    @Override
    protected IndicatorVO indicatorCalculation() {

        List<Fibonacci> fibonacciList = fibonacciAgent.getFiboList();
        List<Double> yList = new ArrayList<Double>();
        int parameterInt = parameter.intValue();

        for (Fibonacci fibonacci : fibonacciList) {
            TrendLineVO resistance = fibonacci.getResistance(lastTick.getHigh(), lastTick.getTimestamp());
            if (resistance != null) {
                // log.info("Is fibonacci but no resistance");
                double y = resistance.getY(lastTick.getTimestamp());
                yList.add(y);
            }
        }

        // if the size is smaller then then requested, it returns null
        if (yList.size() < parameterInt) {
            return null;
        }

        Collections.sort(yList);

        double retValue = yList.get(parameterInt - 1);

        IndicatorVO indicator = new IndicatorVO();
        indicator.setValue(retValue);
        indicator.setChanged((lastValue != null && lastValue != retValue) ? true : false);
        indicator.setDate(lastTick.getTime());

        lastValue = retValue;

        log.debug(lastTick.getHigh() + ", " + indicator.toString());
        return indicator;
    }
}
